/**
 * CSS框架兼容性验证器
 * 确保生成的HTML与实际CSS框架完全匹配
 */

import * as path from 'path'

export interface CSSValidationResult {
  isValid: boolean
  errors: CSSValidationError[]
  warnings: CSSValidationWarning[]
  suggestions: string[]
  score: number
  missingClasses: string[]
  incorrectStructure: StructureError[]
}

export interface CSSValidationError {
  type: 'missing-class' | 'incorrect-structure' | 'wrong-hierarchy' | 'deprecated-class'
  message: string
  location?: string
  suggestion?: string
  correctClass?: string
}

export interface CSSValidationWarning {
  type: 'style-mismatch' | 'layout-issue' | 'accessibility'
  message: string
  suggestion?: string
}

export interface StructureError {
  expected: string
  actual: string
  location: string
  suggestion: string
}

export class CSSFrameworkValidator {

  private static cssClassDefinitions: Map<string, boolean> = new Map()
  private static isInitialized = false

  // 框架定义的正确CSS类名映射
  private static readonly CORRECT_CLASS_MAPPINGS: Record<string, string> = {
    // 按钮类名修复
    'button text': 'funi-btn funi-btn-text',
    'button primary': 'funi-btn funi-btn-primary',
    'button secondary': 'funi-btn funi-btn-default',
    'button': 'funi-btn funi-btn-default',
    'btn': 'funi-btn',
    'btn-primary': 'funi-btn funi-btn-primary',
    'btn-text': 'funi-btn funi-btn-text',

    // 容器类名修复
    'search-container': 'search-area',
    'search-item': 'search-form-item',
    'action-container': 'action-buttons',
    'btn-container': 'action-buttons',
    'content-container': 'container',
    'main-container': 'container',
    'header-container': 'container-header',
    'table-wrapper': 'container-table',

    // 表格类名修复
    'table': 'data-table',
    'funi-table': 'data-table'
  }

  /**
   * 初始化CSS类名定义（从实际CSS文件中提取）
   */
  static async initialize(cssDirectory?: string): Promise<void> {
    if (this.isInitialized) return

    const cssDir = cssDirectory || path.join(process.cwd(), 'dist/pm/assets/css')

    try {
      // 动态导入 fs-extra
      const fs = await import('fs-extra')

      const cssFiles = [
        'funi-framework.css',
        'funi-components.css',
        'funi-themes.css',
        'funi-list.css',
        'funi-form.css'
      ]

      for (const cssFile of cssFiles) {
        const cssPath = path.join(cssDir, cssFile)
        if (await fs.pathExists(cssPath)) {
          const cssContent = await fs.readFile(cssPath, 'utf-8')
          this.extractCSSClasses(cssContent)
        }
      }

      this.isInitialized = true
    } catch (error) {
      console.warn('CSS框架验证器初始化失败:', error)
      // 如果无法读取CSS文件，使用预定义的类名列表
      this.initializeWithPredefinedClasses()
    }
  }

  /**
   * 验证HTML与CSS框架的兼容性
   */
  static async validateCSSCompatibility(html: string, pageType: 'list' | 'form' | 'detail'): Promise<CSSValidationResult> {
    await this.initialize()

    const result: CSSValidationResult = {
      isValid: true,
      errors: [],
      warnings: [],
      suggestions: [],
      score: 100,
      missingClasses: [],
      incorrectStructure: []
    }

    // 检查CSS类名兼容性
    this.checkClassNameCompatibility(html, result)

    // 检查按钮样式规范
    this.checkButtonStyleCompliance(html, result)

    // 检查DOM结构规范
    this.checkDOMStructure(html, pageType, result)

    // 计算最终评分
    result.score = this.calculateCompatibilityScore(result)
    result.isValid = result.score >= 80 && result.errors.length === 0

    return result
  }

  /**
   * 检查CSS类名兼容性
   */
  private static checkClassNameCompatibility(html: string, result: CSSValidationResult): void {
    // 检查错误的按钮类名
    const buttonClassErrors = [
      { pattern: /class="button text"/g, correct: 'funi-btn funi-btn-text' },
      { pattern: /class="button primary"/g, correct: 'funi-btn funi-btn-primary' },
      { pattern: /class="button"/g, correct: 'funi-btn funi-btn-default' }
    ]

    buttonClassErrors.forEach(({ pattern, correct }) => {
      const matches = html.match(pattern)
      if (matches) {
        result.errors.push({
          type: 'deprecated-class',
          message: `发现过时的按钮类名: ${matches[0]}`,
          correctClass: correct,
          suggestion: `请使用框架标准类名: class="${correct}"`
        })
      }
    })
  }

  /**
   * 检查按钮样式规范
   */
  private static checkButtonStyleCompliance(html: string, result: CSSValidationResult): void {
    // 检查操作列按钮是否使用文本样式
    const actionButtonPattern = /<td[^>]*>[\s\S]*?<button[^>]*onclick="[^"]*Action[^"]*"[^>]*>[\s\S]*?<\/td>/g
    const actionButtons = html.match(actionButtonPattern)

    if (actionButtons) {
      actionButtons.forEach(buttonHtml => {
        if (!buttonHtml.includes('funi-btn-text')) {
          result.errors.push({
            type: 'incorrect-structure',
            message: '操作列按钮必须使用文本样式',
            suggestion: '请为操作列按钮添加 funi-btn-text 类名',
            location: '表格操作列'
          })
        }
      })
    }
  }

  /**
   * 检查DOM结构规范
   */
  private static checkDOMStructure(html: string, pageType: string, result: CSSValidationResult): void {
    const requiredStructures = this.getRequiredStructures(pageType)

    requiredStructures.forEach(structure => {
      if (!html.includes(structure.pattern)) {
        result.incorrectStructure.push({
          expected: structure.description,
          actual: '缺失',
          location: structure.location,
          suggestion: structure.suggestion
        })
      }
    })
  }

  /**
   * 获取页面类型所需的DOM结构
   */
  private static getRequiredStructures(pageType: string) {
    const structures = {
      list: [
        {
          pattern: 'class="container"',
          description: '主容器必须使用 container 类',
          location: '页面根元素',
          suggestion: '确保页面根元素使用 <div id="app" class="container">'
        },
        {
          pattern: 'class="action-buttons"',
          description: '操作按钮区域必须使用 action-buttons 类',
          location: '操作按钮容器',
          suggestion: '使用 <div class="action-buttons"> 包装操作按钮'
        }
      ],
      form: [
        {
          pattern: 'class="form-container"',
          description: '表单容器必须使用 form-container 类',
          location: '表单根容器',
          suggestion: '使用 <div class="form-container"> 包装表单内容'
        }
      ],
      detail: [
        {
          pattern: 'class="detail-container"',
          description: '详情容器必须使用 detail-container 类',
          location: '详情页根容器',
          suggestion: '使用 <div class="detail-container"> 包装详情内容'
        }
      ]
    }

    return structures[pageType as keyof typeof structures] || []
  }

  /**
   * 计算兼容性评分
   */
  private static calculateCompatibilityScore(result: CSSValidationResult): number {
    let score = 100

    // 每个错误扣20分
    score -= result.errors.length * 20

    // 每个警告扣5分
    score -= result.warnings.length * 5

    // 每个缺失类名扣10分
    score -= result.missingClasses.length * 10

    // 每个结构问题扣15分
    score -= result.incorrectStructure.length * 15

    return Math.max(0, score)
  }

  /**
   * 获取正确的CSS类名映射
   */
  static getCorrectClassMapping(): Record<string, string> {
    return this.CORRECT_CLASS_MAPPINGS
  }

  /**
   * 获取正确的DOM结构模板
   */
  static getCorrectDOMStructure(pageType: string): string {
    const templates = {
      list: `<div id="app" class="container">
  <div class="container-header">
    <div class="search-area collapsed">
      <form class="search-form">
        <div class="search-form-item">
          <label>标签:</label>
          <input type="text" />
        </div>
        <div class="search-form-item search-buttons-item">
          <button class="funi-btn funi-btn-primary">查询</button>
          <button class="funi-btn funi-btn-default">重置</button>
        </div>
      </form>
    </div>
  </div>
  <div class="container-table">
    <div class="action-buttons">
      <button class="funi-btn funi-btn-primary">新建</button>
    </div>
    <div class="table-container">
      <table class="data-table">
        <thead>...</thead>
        <tbody>...</tbody>
      </table>
    </div>
  </div>
</div>`,
      form: `<div id="app" class="container">
  <div class="form-container">
    <div class="form-section-title">表单标题</div>
    <form class="form-grid">
      <div class="form-item-row">
        <label class="form-item-label">标签:</label>
        <div class="form-item-value">
          <input type="text" />
        </div>
      </div>
    </form>
  </div>
</div>`,
      detail: `<div id="app" class="container">
  <div class="detail-container">
    <div class="detail-section-title">详情标题</div>
    <div class="detail-grid">
      <div class="detail-item-row">
        <label class="detail-item-label">标签:</label>
        <div class="detail-item-value">值</div>
      </div>
    </div>
  </div>
</div>`
    }

    return templates[pageType as keyof typeof templates] || templates.list
  }

  /**
   * 使用预定义的CSS类名列表初始化（备用方案）
   */
  private static initializeWithPredefinedClasses(): void {
    const predefinedClasses = [
      // 布局相关
      'container', 'container-header', 'container-table',

      // 搜索相关
      'search-area', 'search-form', 'search-form-item', 'search-buttons-item',
      'collapsed', 'date-range-picker',

      // 按钮相关 - 使用正确的框架类名
      'action-buttons', 'funi-btn', 'funi-btn-primary', 'funi-btn-text', 'funi-btn-default',

      // 表格相关
      'table-container', 'data-table', 'pagination-container',

      // 表单相关
      'form-container', 'form-section-title', 'form-grid',
      'form-item-row', 'form-item-label', 'form-item-value',
      'input-and-tip-wrapper', 'form-item-tip', 'required',

      // 详情页面相关
      'detail-grid', 'detail-section-title', 'detail-item',

      // 菜单相关
      'funi-menu', 'funi-menu-list', 'funi-menu-item', 'funi-menu-link',
      'funi-menu-text', 'funi-menu-icon', 'funi-menu-group',
      'funi-menu-group-title', 'funi-menu-group-toggle',

      // 通用组件
      'tabs', 'tab-item', 'active', 'table-link'
    ]

    for (const className of predefinedClasses) {
      this.cssClassDefinitions.set(className, true)
    }

    this.isInitialized = true
  }

  /**
   * 验证HTML与CSS框架的兼容性
   */
  static async validateCSSCompatibility(html: string, pageType: 'list' | 'form' | 'detail'): Promise<CSSValidationResult> {
    await this.initialize()

    const result: CSSValidationResult = {
      isValid: true,
      errors: [],
      warnings: [],
      suggestions: [],
      score: 100,
      missingClasses: [],
      incorrectStructure: []
    }

    // 提取HTML中使用的CSS类名
    const usedClasses = this.extractHTMLClasses(html)
    
    // 检查CSS类名是否存在
    this.validateClassExistence(usedClasses, result)
    
    // 检查DOM结构是否符合框架规范
    this.validateDOMStructure(html, pageType, result)
    
    // 检查特定页面类型的结构规范
    this.validatePageSpecificStructure(html, pageType, result)
    
    // 计算最终分数
    result.score = this.calculateCompatibilityScore(result)
    result.isValid = result.errors.length === 0 && result.score >= 80

    return result
  }

  /**
   * 获取正确的CSS类名映射（用于修复建议）
   */
  static getCorrectClassMapping(): Record<string, string> {
    return {
      // 搜索区域相关
      'search-container': 'search-area',
      'search-item': 'search-form-item',
      'search-input': 'search-form-item input',
      'search-select': 'search-form-item select',
      
      // 操作按钮相关
      'action-container': 'action-buttons',
      'action-button': 'button',
      'btn-container': 'action-buttons',
      
      // 布局容器相关
      'content-container': 'container',
      'main-container': 'container',
      'page-container': 'container',
      'header-container': 'container-header',
      'table-wrapper': 'container-table',
      
      // 表格相关
      'table-container': 'table-container', // 这个是正确的
      'data-grid': 'data-table',
      'list-table': 'data-table',
      
      // 表单相关
      'form-container': 'form-container', // 这个是正确的
      'form-item': 'form-item-row',
      'form-label': 'form-item-label',
      'form-input': 'form-item-value',
      
      // 分页相关
      'pagination': 'pagination-container',
      'page-nav': 'pagination-container'
    }
  }

  /**
   * 获取正确的DOM结构模板
   */
  static getCorrectDOMStructure(pageType: 'list' | 'form' | 'detail'): string {
    const structures = {
      list: `
<div id="app" class="container">
  <div class="container-header">
    <div class="search-area collapsed">
      <form class="search-form">
        <div class="search-form-item">
          <label>标签:</label>
          <input type="text" />
        </div>
        <div class="search-form-item search-buttons-item">
          <button class="button primary">查询</button>
          <button class="button">重置</button>
        </div>
      </form>
    </div>
  </div>
  <div class="container-table">
    <div class="action-buttons">
      <button class="button primary">新建</button>
    </div>
    <div class="table-container">
      <table class="data-table">
        <thead>...</thead>
        <tbody>...</tbody>
      </table>
    </div>
  </div>
</div>`,
      form: `
<div id="app" class="form-container">
  <div class="form-section-title">标题</div>
  <form class="form-grid">
    <div class="form-item-row">
      <label class="form-item-label">标签:</label>
      <div class="form-item-value">
        <div class="input-and-tip-wrapper">
          <input type="text" />
        </div>
      </div>
    </div>
  </form>
</div>`,
      detail: `
<div id="app" class="container">
  <div class="detail-section-title">标题</div>
  <div class="detail-grid">
    <div class="detail-item">
      <label>标签:</label>
      <span>值</span>
    </div>
  </div>
</div>`
    }
    return structures[pageType]
  }

  private static extractCSSClasses(cssContent: string): void {
    // 提取CSS类名的正则表达式
    const classRegex = /\.([a-zA-Z][a-zA-Z0-9_-]*)/g
    let match

    while ((match = classRegex.exec(cssContent)) !== null) {
      const className = match[1]
      // 排除伪类和媒体查询中的类名
      if (!className.includes(':') && !className.includes('@')) {
        this.cssClassDefinitions.set(className, true)
      }
    }
  }

  private static extractHTMLClasses(html: string): string[] {
    const classRegex = /class=["']([^"']+)["']/g
    const classes: string[] = []
    let match

    while ((match = classRegex.exec(html)) !== null) {
      const classNames = match[1].split(/\s+/).filter(name => name.trim())
      classes.push(...classNames)
    }

    return [...new Set(classes)] // 去重
  }

  private static validateClassExistence(usedClasses: string[], result: CSSValidationResult): void {
    const correctMapping = this.getCorrectClassMapping()

    for (const className of usedClasses) {
      if (!this.cssClassDefinitions.has(className)) {
        // 检查是否有正确的替代类名
        const correctClass = correctMapping[className]
        
        if (correctClass) {
          result.errors.push({
            type: 'missing-class',
            message: `使用了不存在的CSS类: ${className}`,
            suggestion: `应该使用: ${correctClass}`,
            correctClass
          })
        } else {
          result.errors.push({
            type: 'missing-class',
            message: `CSS类不存在: ${className}`,
            suggestion: '请检查CSS框架文档，使用正确的类名'
          })
        }
        
        result.missingClasses.push(className)
      }
    }
  }

  private static validateDOMStructure(html: string, pageType: string, result: CSSValidationResult): void {
    // 检查列表页面的DOM结构
    if (pageType === 'list') {
      this.validateListPageStructure(html, result)
    } else if (pageType === 'form') {
      this.validateFormPageStructure(html, result)
    } else if (pageType === 'detail') {
      this.validateDetailPageStructure(html, result)
    }
  }

  private static validateListPageStructure(html: string, result: CSSValidationResult): void {
    // 检查必需的结构层次
    const requiredStructures = [
      {
        pattern: /<div[^>]*class="[^"]*container[^"]*"[^>]*>[\s\S]*<div[^>]*class="[^"]*container-header[^"]*"[^>]*>/,
        message: '缺少正确的页面容器结构',
        suggestion: '使用 <div class="container"> 包含 <div class="container-header">'
      },
      {
        pattern: /<div[^>]*class="[^"]*search-area[^"]*"[^>]*>/,
        message: '搜索区域应使用 search-area 类名',
        suggestion: '将 search-container 改为 search-area'
      },
      {
        pattern: /<div[^>]*class="[^"]*search-form-item[^"]*"[^>]*>/,
        message: '搜索项应使用 search-form-item 类名',
        suggestion: '将 search-item 改为 search-form-item'
      },
      {
        pattern: /<div[^>]*class="[^"]*action-buttons[^"]*"[^>]*>/,
        message: '操作按钮区域应使用 action-buttons 类名',
        suggestion: '将 action-container 改为 action-buttons'
      },
      {
        pattern: /<div[^>]*class="[^"]*container-table[^"]*"[^>]*>/,
        message: '表格区域应包装在 container-table 中',
        suggestion: '将操作按钮和表格包装在 <div class="container-table"> 中'
      }
    ]

    for (const structure of requiredStructures) {
      if (!structure.pattern.test(html)) {
        result.incorrectStructure.push({
          expected: structure.suggestion,
          actual: '当前结构不符合要求',
          location: '页面结构',
          suggestion: structure.suggestion
        })
        
        result.errors.push({
          type: 'incorrect-structure',
          message: structure.message,
          suggestion: structure.suggestion
        })
      }
    }
  }

  private static validateFormPageStructure(html: string, result: CSSValidationResult): void {
    // 表单页面结构验证
    if (!html.includes('form-container')) {
      result.errors.push({
        type: 'incorrect-structure',
        message: '表单页面缺少 form-container 容器',
        suggestion: '使用 <div class="form-container"> 作为表单外层容器'
      })
    }

    if (!html.includes('form-grid')) {
      result.errors.push({
        type: 'incorrect-structure',
        message: '表单缺少 form-grid 布局类',
        suggestion: '使用 <form class="form-grid"> 实现标准布局'
      })
    }
  }

  private static validateDetailPageStructure(html: string, result: CSSValidationResult): void {
    // 详情页面结构验证
    if (!html.includes('detail-grid')) {
      result.warnings.push({
        type: 'layout-issue',
        message: '详情页面建议使用 detail-grid 布局',
        suggestion: '使用 <div class="detail-grid"> 实现详情页面布局'
      })
    }
  }

  private static validatePageSpecificStructure(html: string, pageType: string, result: CSSValidationResult): void {
    // 检查页面特定的结构要求
    if (pageType === 'list') {
      // 检查搜索区域是否正确嵌套
      if (html.includes('search-area') && !html.includes('container-header')) {
        result.warnings.push({
          type: 'layout-issue',
          message: 'search-area 应该嵌套在 container-header 中',
          suggestion: '将搜索区域放在 <div class="container-header"> 内'
        })
      }

      // 检查操作按钮是否在正确位置
      if (html.includes('action-buttons') && !html.includes('container-table')) {
        result.warnings.push({
          type: 'layout-issue',
          message: 'action-buttons 应该在 container-table 内',
          suggestion: '将操作按钮放在 <div class="container-table"> 内'
        })
      }
    }
  }

  private static calculateCompatibilityScore(result: CSSValidationResult): number {
    let score = 100
    score -= result.errors.length * 20  // 每个错误扣20分
    score -= result.warnings.length * 10 // 每个警告扣10分
    score -= result.missingClasses.length * 15 // 每个缺失类名扣15分
    return Math.max(0, score)
  }
}
